export class AlipaySubmit {
  public alipayConfig: any;
  public alipayGatewayNew: any;

  constructor(alipayConfig) {
    this.alipayConfig = alipayConfig;
    this.alipayGatewayNew = `${this.alipayConfig.apiurl}submit.php?`;
  }

  // 生成签名结果
  buildRequestMysign(paraSort) {
    // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
    const prestr = this.createLinkstring(paraSort);

    // 生成签名结果
    const mysign = this.md5Sign(prestr, this.alipayConfig.key);

    return mysign;
  }

  // 生成要请求给支付宝的参数数组
  buildRequestPara(paraTemp) {
    // 除去待签名参数数组中的空值和签名参数
    const paraFilter = this.paraFilter(paraTemp);

    // 对待签名参数数组排序
    const paraSort = this.argSort(paraFilter);

    // 生成签名结果
    const mysign = this.buildRequestMysign(paraSort);

    // 签名结果与签名方式加入请求提交参数组中
    paraSort.sign = mysign;
    paraSort.sign_type = this.alipayConfig.sign_type.toUpperCase().trim();

    return paraSort;
  }

  // 生成要请求给支付宝的参数数组字符串
  buildRequestParaToString(paraTemp) {
    // 待请求参数数组
    const para = this.buildRequestPara(paraTemp);

    // 把参数组中所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串，并对字符串做urlencode编码
    const requestData = this.createLinkstringUrlencode(para);

    return requestData;
  }

  // 建立请求，以表单HTML形式构造（默认）
  buildRequestForm(paraTemp, method = "POST", buttonName = "正在跳转") {
    // 待请求参数数组
    const para = this.buildRequestPara(paraTemp);

    let sHtml = `<form id='alipaysubmit' name='alipaysubmit' action='${
      this.alipayGatewayNew
    }_input_charset=${this.alipayConfig.input_charset.toLowerCase()}' method='${method}'>`;
    for (const [key, val] of Object.entries(para)) {
      sHtml += `<input type='hidden' name='${key}' value='${val}'/>`;
    }

    // submit按钮控件请不要含有name属性
    sHtml += `<input type='submit' value='${buttonName}'></form>`;
    sHtml += `<script>document.forms['alipaysubmit'].submit();</script>`;

    return sHtml;
  }

  // 辅助函数
  createLinkstring(para) {
    return Object.entries(para)
      .map(([key, value]) => `${key}=${value}`)
      .join("&");
  }

  md5Sign(prestr, key) {
    const crypto = require("crypto");
    return crypto
      .createHash("md5")
      .update(prestr + key)
      .digest("hex");
  }

  paraFilter(para) {
    const result = {};
    for (const [key, value] of Object.entries(para)) {
      if (value !== "" && key !== "sign" && key !== "sign_type") {
        result[key] = value;
      }
    }
    return result;
  }

  argSort(para) {
    return Object.fromEntries(Object.entries(para).sort());
  }

  createLinkstringUrlencode(para) {
    return Object.entries(para)
      .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value as any)}`)
      .join("&");
  }
}

// // 示例使用
// const alipayConfig = {
//   apiurl: "https://m1.duai1.cn/",
//   key: "fSY3ZWEolQw",
//   sign_type: "MD5",
//   input_charset: "UTF-8",
// };

// const alipaySubmit = new AlipaySubmit(alipayConfig);

// const paraTemp = {
//   pid: "196309431", // 商户ID
//   type: "wxpay", // 支付方式
//   out_trade_no: "20231020145000001", // 商户订单号
//   notify_url: "https://www.cccyun.cc/notify_url.php", // 异步通知地址
//   return_url: "https://www.cccyun.cc/return_url.php", // 页面跳转通知地址
//   name: "VIP会员", // 商品名称
//   money: "1.00", // 商品金额
//   sitename: "彩虹云任务", // 网站名称
// };

// const params: any = alipaySubmit.buildRequestPara(paraTemp);

// const url = `https://m1.duai1.cn/submit.php?${querystring.stringify(params)}`;
